import flet as ft
from db_operations import ProductDatabase


class ProductManager:
    def __init__(self):
        try:
            self.db = ProductDatabase()
            self.current_sort = {'column': 'created_date', 'order': 'DESC'}
            self.current_page = 1
            self.per_page = 10
            self.search_term = ""
        except Exception as e:
            print(f"初始化时出错: {str(e)}")
            self.current_sort = {'column': 'created_date', 'order': 'DESC'}

        ft.app(target=self.main)

    def main(self, page: ft.Page):
        self.page = page
        page.title = "商品管理系统"
        page.window.width = 1200
        page.window.height = 850
        page.padding = 20
        page.theme_mode = ft.ThemeMode.LIGHT
        page.bgcolor = ft.colors.GREY_50

        # 修改容器样式定义
        container_style = {
            "bgcolor": ft.colors.WHITE,
            "padding": 20,
            "border_radius": 10,
            "shadow": ft.BoxShadow(
                spread_radius=1,
                blur_radius=10,
                color=ft.colors.GREY_300,
                offset=ft.Offset(0, 2),
            ),
            "width": 1160
        }

        # 标题区域
        title = ft.Text("商品管理系统", size=32, weight=ft.FontWeight.BOLD)
        subtitle = ft.Text("管理您的商品信息", size=16, color=ft.colors.GREY_700)

        # 输入字段样式优化
        input_style = {
            "width": 250,
            "height": 45,
            "border_radius": 8,
            "focused_border_color": ft.colors.BLUE_400,
            "border_color": ft.colors.GREY_300,
        }

        self.name_input = ft.TextField(
            label="商品名称 *",
            hint_text="输商品名称",
            prefix_icon=ft.icons.SHOPPING_BAG,
            **input_style
        )
        self.price_input = ft.TextField(
            label="价格 *",
            hint_text="输入商品价格",
            prefix_icon=ft.icons.ATTACH_MONEY,
            **input_style
        )
        self.creator_input = ft.TextField(
            label="创建人",
            hint_text="输入创建人姓名（默认admin）",
            prefix_icon=ft.icons.PERSON,
            **input_style
        )

        # 修改搜索输入框样式
        self.search_input = ft.TextField(
            label="搜索商品",
            width=200,
            height=45,
            prefix_icon=ft.icons.SEARCH,
            hint_text="输入商品名称",
            border_radius=8,
            on_submit=self.search_products
        )

        # 搜索区域容器
        search_container = ft.Container(
            content=ft.Row(
                [
                    ft.Row(  # 搜索部分
                        [
                            self.search_input,
                            ft.ElevatedButton(
                                "搜索",
                                icon=ft.icons.SEARCH,
                                style=ft.ButtonStyle(
                                    shape=ft.RoundedRectangleBorder(radius=8),
                                    padding=ft.padding.only(left=15, right=15, top=12, bottom=12),
                                ),
                                on_click=self.search_products
                            ),
                        ],
                        spacing=10,
                    ),
                ],
                alignment=ft.MainAxisAlignment.START,
            ),
            **{
                **container_style,
                "padding": ft.padding.only(left=20, right=20, top=10, bottom=10),
                "width": 1160
            }
        )

        # 首先创建表格（移到容器创建之前）
        self.table = ft.DataTable(
            heading_row_color=ft.colors.BLUE_GREY_50,
            heading_row_height=50,
            data_row_color={
                ft.MaterialState.DEFAULT: ft.colors.WHITE,
                ft.MaterialState.HOVERED: ft.colors.BLUE_50,
            },
            data_row_min_height=45,
            column_spacing=5,
            horizontal_margin=5,
            columns=[
                self.create_column("序号", 'number', 50),
                self.create_column("商品名称", 'name', 200),
                self.create_column("价格", 'price', 80),
                self.create_column("创建日期", 'created_date', 140),
                self.create_column("修改日期", 'modified_date', 140),
                self.create_column("创建人", 'created_by', 100),
                ft.DataColumn(
                    ft.Container(
                        content=ft.Text("操作", size=14, weight=ft.FontWeight.BOLD),
                        width=80
                    ),
                    numeric=True
                ),
            ],
            rows=[]
        )

        # 商品列表标题和添加按钮行
        list_header = ft.Row(
            [
                ft.Row(  # 左侧标题和说明
                    [
                        ft.Text("商品列表", size=20, weight=ft.FontWeight.BOLD),
                        ft.Container(
                            content=ft.Text(
                                "（只显示最近添加的15条数据）",
                                size=12,
                                color=ft.colors.RED_400,
                                style=ft.TextStyle(italic=True)
                            ),
                            padding=ft.padding.only(left=10, top=5)
                        ),
                    ],
                ),
                ft.ElevatedButton(
                    "添加商品",
                    icon=ft.icons.ADD,
                    style=ft.ButtonStyle(
                        shape=ft.RoundedRectangleBorder(radius=8),
                        padding=ft.padding.only(left=15, right=15, top=12, bottom=12),
                        bgcolor=ft.colors.BLUE_400,
                    ),
                    on_click=lambda e: self.show_add_dialog()
                ),
            ],
            alignment=ft.MainAxisAlignment.SPACE_BETWEEN,
        )

        # 表格容器样式优化
        table_container = ft.Container(
            content=ft.Column([
                list_header,
                ft.Divider(height=10, color=ft.colors.GREY_300),
                # 修改ListView的配置
                ft.ListView(
                    controls=[self.table],
                    height=400,
                    spacing=0,
                    padding=0,
                    auto_scroll=False  # 禁用自动滚动
                ),
                ft.Divider(height=10, color=ft.colors.GREY_300),
                self.create_pagination(self.db.get_total_count()),
            ]),
            **{
                **container_style,
                "padding": 10,
            }
        )

        # 主布局
        page.add(
            ft.Container(
                content=ft.Column([
                    # 标题区域
                    ft.Container(
                        content=ft.Column([
                            title,
                            subtitle,
                        ]),
                        padding=ft.padding.only(left=20, right=20, bottom=20)
                    ),
                    # 功能区域
                    search_container,
                    ft.Divider(height=20, color=ft.colors.TRANSPARENT),
                    table_container,
                ]),
                width=1200,
                padding=20,
            )
        )

        self.update_table()

    def add_product(self, e):
        try:
            name = self.name_input.value
            price_text = self.price_input.value
            creator = self.creator_input.value or "admin"

            # 验证必填项
            if not name:
                self.show_error_dialog("商品名称不能为空！")
                return

            if not price_text:
                self.show_error_dialog("价格不能空！")
                return

            try:
                price = float(price_text)
                if price <= 0:
                    self.show_error_dialog("价格必须大于0！")
                    return
            except ValueError:
                self.show_error_dialog("请输入有效的价格！")
                return

            self.db.add_product(name, price, creator)
            self.clear_inputs()
            self.update_table()

        except Exception as e:
            self.show_error_dialog(f"添加失败：{str(e)}")

    def update_product(self, e, id):
        try:
            name = self.name_input.value
            price_text = self.price_input.value

            # 验证必填项
            if not name:
                self.show_error_dialog("商品名称不能为空！")
                return

            if not price_text:
                self.show_error_dialog("价格不能为空！")
                return

            try:
                price = float(price_text)
                if price <= 0:
                    self.show_error_dialog("价格必须大于0！")
                    return
            except ValueError:
                self.show_error_dialog("请输入有效的价格！")
                return

            self.db.update_product(id, name, price)
            self.clear_inputs()
            self.update_table()

        except Exception as e:
            self.show_error_dialog(f"更新失败：{str(e)}")

    def delete_product(self, e, id):
        def confirm_delete(e):
            self.db.delete_product(id)
            self.update_table()
            dialog.open = False
            self.page.update()

        def close_dialog(e):
            dialog.open = False
            self.page.update()

        # 创建确认删除对话框
        dialog = ft.AlertDialog(
            modal=True,
            title=ft.Text("确认删除", size=20, weight=ft.FontWeight.BOLD),
            content=ft.Text("确定要删除这个商品吗？此操作不可恢复。"),
            actions=[
                ft.TextButton("取消", on_click=close_dialog),
                ft.ElevatedButton(
                    "删除",
                    color=ft.colors.WHITE,
                    bgcolor=ft.colors.RED_400,
                    on_click=confirm_delete,
                    style=ft.ButtonStyle(
                        shape=ft.RoundedRectangleBorder(radius=8),
                    ),
                ),
            ],
            actions_alignment=ft.MainAxisAlignment.END,
        )

        self.page.overlay.append(dialog)  # 使用 overlay.append
        dialog.open = True
        self.page.update()

    def search_products(self, e):
        self.search_term = self.search_input.value
        self.current_page = 1  # 重置到第一页
        products = self.db.search_products(
            self.search_term,
            sort_by=self.current_sort['column'],
            sort_order=self.current_sort['order'],
            page=self.current_page,
            per_page=self.per_page
        )
        total_count = self.db.get_search_count(self.search_term)
        self.update_table_rows(products)

        # 更新分页控件
        if hasattr(self, 'page'):
            # 找到表格容器并更新分页
            for control in self.page.controls:
                if isinstance(control, ft.Container):
                    for child in control.content.controls:
                        if isinstance(child, ft.Container) and len(child.content.controls) > 3:
                            # 更新分页控件
                            child.content.controls[-1] = self.create_pagination(total_count)
                            child.update()
                            break

    def clear_inputs(self):
        self.name_input.value = ""
        self.price_input.value = ""
        self.creator_input.value = ""
        self.name_input.update()
        self.price_input.update()
        self.creator_input.update()

    def update_table(self):
        products = self.db.get_all_products(
            sort_by=self.current_sort['column'],
            sort_order=self.current_sort['order'],
            page=self.current_page,
            per_page=self.per_page
        )
        total_count = self.db.get_total_count()
        self.update_table_rows(products)

        # 更新分页控件
        if hasattr(self, 'page'):
            # 找到表格容器并更新分页
            for control in self.page.controls:
                if isinstance(control, ft.Container):
                    for child in control.content.controls:
                        if isinstance(child, ft.Container) and len(child.content.controls) > 3:
                            # 更新分页控件
                            child.content.controls[-1] = self.create_pagination(total_count)
                            child.update()
                            break

    def update_table_rows(self, products):
        self.table.rows.clear()

        if not products:  # 如果没有数据
            empty_row = ft.DataRow(
                cells=[
                    # 创建7个单元格，只在中间的单元格显示文本
                    ft.DataCell(ft.Container()),  # 空单元格
                    ft.DataCell(ft.Container()),  # 空单元格
                    ft.DataCell(ft.Container()),  # 空单元格
                    ft.DataCell(  # 中间单元格显示"暂无数据"
                        ft.Container(
                            content=ft.Text(
                                "暂无数据",
                                size=14,
                                color=ft.colors.GREY_500,
                                text_align=ft.TextAlign.CENTER,
                            ),
                            alignment=ft.alignment.center,
                            expand=True
                        )
                    ),
                    ft.DataCell(ft.Container()),  # 空单元格
                    ft.DataCell(ft.Container()),  # 空单元格
                    ft.DataCell(ft.Container()),  # 空单元格
                ]
            )
            self.table.rows.append(empty_row)
        else:
            for index, product in enumerate(products, start=1):
                # 处理商品名称的换行
                name = product[1]
                formatted_name = '\n'.join([name[i:i + 5] for i in range(0, len(name), 5)])

                self.table.rows.append(
                    ft.DataRow(
                        cells=[
                            ft.DataCell(ft.Text(str(index), size=13)),
                            ft.DataCell(
                                ft.Container(
                                    content=ft.Text(
                                        formatted_name,
                                        size=13,
                                        text_align=ft.TextAlign.LEFT,
                                        width=180,
                                        max_lines=None
                                    ),
                                    padding=ft.padding.all(5)
                                )
                            ),
                            ft.DataCell(ft.Text(f"¥{product[2]:.2f}", size=13)),
                            ft.DataCell(ft.Text(product[3], size=13)),
                            ft.DataCell(ft.Text(product[4], size=13)),
                            ft.DataCell(ft.Text(product[5], size=13)),
                            ft.DataCell(
                                ft.Row(
                                    [
                                        ft.IconButton(
                                            icon=ft.icons.EDIT,
                                            icon_color=ft.colors.BLUE_400,
                                            tooltip="编辑",
                                            on_click=lambda e, p=product: self.show_edit_dialog(p),
                                            icon_size=16
                                        ),
                                        ft.IconButton(
                                            icon=ft.icons.DELETE_FOREVER,
                                            icon_color=ft.colors.RED_400,
                                            tooltip="删除",
                                            on_click=lambda e, id=product[0]: self.delete_product(e, id),
                                            icon_size=16
                                        )
                                    ],
                                    alignment=ft.MainAxisAlignment.CENTER,
                                    spacing=0
                                )
                            )
                        ]
                    )
                )
        self.table.update()

    def create_column(self, title, column_id, width=None):
        return ft.DataColumn(
            ft.Row(
                [
                    ft.Container(
                        content=ft.Row(
                            [
                                ft.Text(title, size=14, weight=ft.FontWeight.BOLD),
                                self.get_sort_icon(column_id)
                            ],
                            spacing=5
                        ),
                        width=width
                    )
                ]
            ),
            on_sort=lambda e: self.sort_table(column_id)
        )

    def get_sort_icon(self, column):
        if self.current_sort['column'] != column:
            return ft.Icon(ft.icons.IMPORT_EXPORT, size=14, opacity=0.3)
        else:
            return ft.Icon(
                ft.icons.ARROW_UPWARD if self.current_sort['order'] == 'ASC' else ft.icons.ARROW_DOWNWARD,
                size=14,
                color=ft.colors.BLUE_400
            )

    def sort_table(self, column):
        if self.current_sort['column'] == column:
            self.current_sort['order'] = 'DESC' if self.current_sort['order'] == 'ASC' else 'ASC'
        else:
            self.current_sort['column'] = column
            self.current_sort['order'] = 'ASC'

        # 保存排序偏好到数据库
        self.db.save_sort_preference(self.current_sort['column'], self.current_sort['order'])

        # 更新表格显示
        self.update_table()

        # 更新所有列的排序图标
        for col in self.table.columns:
            if isinstance(col.label, ft.Row):
                container = col.label.controls[0]  # 获取Container
                if isinstance(container, ft.Container):
                    row = container.content  # 获取Row
                    if isinstance(row, ft.Row):
                        text = row.controls[0]  # 获取Text
                        if isinstance(text, ft.Text):
                            column_id = text.value.lower().replace(' ', '_')
                            row.controls[1] = self.get_sort_icon(column_id)

        self.table.update()

    def show_error_dialog(self, message):
        def close_dialog(e):
            dialog.open = False
            self.page.update()

        dialog = ft.AlertDialog(
            title=ft.Text("错误"),
            content=ft.Text(message),
            actions=[
                ft.TextButton("确定", on_click=close_dialog),
            ]
        )
        self.page.overlay.append(dialog)  # 使用 overlay.append 替代直接赋值
        dialog.open = True
        self.page.update()

    def show_add_dialog(self):
        # 创建输入字段
        name_input = ft.TextField(
            label="商品名称 *",
            hint_text="输入商品名称",
            border_radius=8,
            width=300
        )
        price_input = ft.TextField(
            label="价格 *",
            hint_text="输入商品价格",
            border_radius=8,
            width=300
        )
        creator_input = ft.TextField(
            label="创建人",
            hint_text="输入创建人姓名（默认admin）",
            border_radius=8,
            width=300
        )

        def save_product(e):
            try:
                name = name_input.value
                price_text = price_input.value
                creator = creator_input.value or "admin"

                # 验证必填项
                if not name:
                    self.show_error_dialog("商品名称不能为空！")
                    return

                if not price_text:
                    self.show_error_dialog("价格不能为空！")
                    return

                try:
                    price = float(price_text)
                    if price <= 0:
                        self.show_error_dialog("价格必须大于0！")
                        return
                except ValueError:
                    self.show_error_dialog("请输入有效的价格！")
                    return

                self.db.add_product(name, price, creator)
                self.update_table()
                dialog.open = False
                self.page.update()

            except Exception as e:
                self.show_error_dialog(f"添加失败：{str(e)}")

        def close_dialog(e):
            dialog.open = False
            self.page.update()

        # 修改对话框显示部分
        dialog = ft.AlertDialog(
            modal=True,
            title=ft.Text("添加商品", size=20, weight=ft.FontWeight.BOLD),
            content=ft.Container(
                content=ft.Column(
                    [
                        name_input,
                        ft.Divider(height=10, color=ft.colors.TRANSPARENT),
                        price_input,
                        ft.Divider(height=10, color=ft.colors.TRANSPARENT),
                        creator_input,
                        ft.Divider(height=10, color=ft.colors.TRANSPARENT),
                        ft.Text("* 必填项", color=ft.colors.GREY_500, italic=True),
                    ],
                    tight=True,
                ),
                padding=20,
            ),
            actions=[
                ft.TextButton("取消", on_click=close_dialog),
                ft.ElevatedButton(
                    "保存",
                    on_click=save_product,
                    style=ft.ButtonStyle(
                        shape=ft.RoundedRectangleBorder(radius=8),
                    ),
                ),
            ],
            actions_alignment=ft.MainAxisAlignment.END,
        )

        self.page.overlay.append(dialog)  # 使用 overlay.append
        dialog.open = True
        self.page.update()

    def show_edit_dialog(self, product_data):
        # 创建输入字段并填充现有数据
        name_input = ft.TextField(
            label="商品名称 *",
            value=product_data[1],  # 商品名称
            hint_text="输入商品名称",
            border_radius=8,
            width=300
        )
        price_input = ft.TextField(
            label="价格 *",
            value=str(product_data[2]),  # 价格
            hint_text="输入商品价格",
            border_radius=8,
            width=300
        )
        creator_input = ft.TextField(
            label="创建人",
            value=product_data[5],  # 创建人
            hint_text="输入创建人姓名",
            border_radius=8,
            width=300,
            read_only=True  # 创建人不允修改
        )

        def save_edit(e):
            try:
                name = name_input.value
                price_text = price_input.value

                # 验证必填项
                if not name:
                    self.show_error_dialog("商品名称不能为空！")
                    return

                if not price_text:
                    self.show_error_dialog("价格不能为空！")
                    return

                try:
                    price = float(price_text)
                    if price <= 0:
                        self.show_error_dialog("价格必须大于0！")
                        return
                except ValueError:
                    self.show_error_dialog("请输入有效的价格！")
                    return

                self.db.update_product(product_data[0], name, price)
                self.update_table()
                dialog.open = False
                self.page.update()

            except Exception as e:
                self.show_error_dialog(f"更新失败：{str(e)}")

        def close_dialog(e):
            dialog.open = False
            self.page.update()

        # 修改对话框显示部分
        dialog = ft.AlertDialog(
            modal=True,
            title=ft.Text("编辑商品", size=20, weight=ft.FontWeight.BOLD),
            content=ft.Container(
                content=ft.Column(
                    [
                        name_input,
                        ft.Divider(height=10, color=ft.colors.TRANSPARENT),
                        price_input,
                        ft.Divider(height=10, color=ft.colors.TRANSPARENT),
                        creator_input,
                        ft.Divider(height=10, color=ft.colors.TRANSPARENT),
                        ft.Text("* 必填项", color=ft.colors.GREY_500, italic=True),
                    ],
                    tight=True,
                ),
                padding=20,
            ),
            actions=[
                ft.TextButton("取消", on_click=close_dialog),
                ft.ElevatedButton(
                    "保存",
                    on_click=save_edit,
                    style=ft.ButtonStyle(
                        shape=ft.RoundedRectangleBorder(radius=8),
                    ),
                ),
            ],
            actions_alignment=ft.MainAxisAlignment.END,
        )

        self.page.overlay.append(dialog)  # 使用 overlay.append
        dialog.open = True
        self.page.update()

    def show_delete_confirm(self, product_id, edit_dialog=None):
        def confirm_delete(e):
            if edit_dialog:
                edit_dialog.open = False
            self.db.delete_product(product_id)
            self.update_table()
            confirm_dialog.open = False
            self.page.update()

        def close_dialog(e):
            confirm_dialog.open = False
            self.page.update()

        # 创建确认删除对话框
        confirm_dialog = ft.AlertDialog(
            modal=True,
            title=ft.Text("确认删除", size=20, weight=ft.FontWeight.BOLD),
            content=ft.Text("确定要删除这个商品吗？此操作不可恢复。"),
            actions=[
                ft.TextButton("取消", on_click=close_dialog),
                ft.ElevatedButton(
                    "删除",
                    color=ft.colors.WHITE,
                    bgcolor=ft.colors.RED_400,
                    on_click=confirm_delete,
                    style=ft.ButtonStyle(
                        shape=ft.RoundedRectangleBorder(radius=8),
                    ),
                ),
            ],
            actions_alignment=ft.MainAxisAlignment.END,
        )

        self.page.overlay.append(confirm_dialog)  # 使用 overlay.append
        confirm_dialog.open = True
        self.page.update()

    # 添加分页控件创方法
    def create_pagination(self, total_count):
        total_pages = (total_count + self.per_page - 1) // self.per_page

        def change_page(new_page):
            if 1 <= new_page <= total_pages:
                self.current_page = new_page
                self.update_table()

        pagination = ft.Row(
            [
                ft.IconButton(
                    icon=ft.icons.ARROW_BACK,
                    on_click=lambda e: change_page(self.current_page - 1),
                    disabled=self.current_page == 1,
                ),
                ft.Text(f"第 {self.current_page} 页，共 {total_pages} 页"),
                ft.IconButton(
                    icon=ft.icons.ARROW_FORWARD,
                    on_click=lambda e: change_page(self.current_page + 1),
                    disabled=self.current_page == total_pages,
                ),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
        )
        return pagination


if __name__ == "__main__":
    ProductManager()
